/**
 * @copyright SilverBiology, LLC
 * @author Michael Giddens
 * @website http://www.silverbiology.com
*/

Ext.namespace('GBIF');
Ext.namespace('GBIF.GeoSpatial');

GBIF.GeoSpatial.CenterPanel = function(config){

	this.tabmanager = new GBIF.GeoSpatial.TabManager({
					region: 'east'
				,	collapsible:true
				,	collapsedMode:'mini'
				,	split:true
	});
	
	this.mapComponent = new GBIF.GeoSpatial.MapComponent({
					region: 'center'
	});

	var clusterlayer = new OpenLayers.Layer.WMS(
                    "GBIF: Cluster1", "http://ogc.gbif.org/wms",
                    {
                    	 width: '512'
                    ,    srs: 'EPSG:4326'
					,	 url:'http://ogc.gbif.org/wms'
                    ,    layers: 'gbif:cluster1'
                    ,    height: '457'
                    ,    styles: ''
                    ,    format: "image/png"
                    ,    tiled: 'true'
					,	 transparent:true
					,	 querable:true
					,    tilesOrigin : this.mapComponent.map.maxExtent.left + ',' + this.mapComponent.map.maxExtent.bottom
                    }
         )
		 
	
	var datagrid = new GBIF.GeoSpatial.DataGrid({
			'columns': [
					{header: "Fid",dataIndex:"fid", id:'fid',width:250}
				,	{header: "count",dataIndex:"count",	editor: new Ext.form.TextField()}
			]
		,	'fields': [
					{name:'fid',type:'string',mapping:'@attributes.fid'}
				,	{name:'count',type:'string'} 
			]	
		,	title:"GBIF: Cluster1"
		,	itemId:"GBIF: Cluster1"
	});
							
	GBIF.GeoSpatial.BUS.fireEvent('addTab', datagrid, this);
	
	datagrid.on('afterEdit',this.commitdataEditChanges,this);
	
		this.mapComponent.map.addLayer(clusterlayer);
	
	/*Drawing controls*/
		
		this.featuredatagrid= this.tabmanager.featuredatagrid
	
		this.featuredatagrid.commit.on('click',this.senddata,this);
		
		this.featuredatagrid.on('rowClick',this.selectfeaturemap,this);
		
		this.featuredatagrid.on('deleteFeature',this.deletefeaturemap,this);
		
		this.featuredatagrid.on('centerToMap',this.moveMapToCenter,this);
	
		this.featuredatagrid.on('afterEdit',this.commitEditChanges,this);
			
	GBIF.GeoSpatial.BUS.on('sendRequest',this.sendRequestForFeature, this);

	
	Ext.apply(this, config, {
			border:false
		,	layout:'border'	
		,	items:[this.mapComponent,this.tabmanager]
		,	width:600
		,	height:600	
		,	listeners: {
				afterrender:function(){
						this.controlPanel();
					}
			}	
	});

	GBIF.GeoSpatial.CenterPanel.superclass.constructor.call(this,config);
}

Ext.extend(GBIF.GeoSpatial.CenterPanel, Ext.Panel, {
	
	callSaveFun:function(){
			this.scope.savetogrid();
		}

,	sendRequestForFeature:function(layer,xy){
	 			var params = {
                    		request: "GetFeatureInfo"
 					 	,	version: layer.params.VERSION   //'1.0.0'
              		    ,	bbox: layer.map.getExtent().toBBOX()
                        ,	x: xy.x
	                    ,	y: xy.y
    	                ,	info_format:'application/vnd.ogc.gml'
        	            ,	query_layers: layer.params.LAYERS
            		    ,	srs: layer.params.SRS   //'EPSG:4326'
                    	,	layers: layer.params.LAYERS
                    	,	styles: ''
                    	,	width: layer.map.size.w
                    	,	height: layer.map.size.h
                    	,	format: 'image/png'
						};
				if (layer.visibility) {
					Ext.Ajax.request({
						url: Config.General.Home.url + "api/getfeatureinfo-proxy.php?url=" + layer.url,
						method: 'POST',
						timeout: 120000,
						scope: this,
						params: params,
						success: function(responseObject){
							var data = Ext.decode(responseObject.responseText);
							this.checkforException(data, layer);
						},
						failure: function(){
							GBIF.GeoSpatial.Notice.msg("Exception", "Service Exception");
						}
					}, this);
				}
		}

,	checkforException:function(data,layer){
				var dataAvailable = (typeof data.FeatureCollection == 'undefined') ? false : true;
				if (dataAvailable) {
					var dataAvailable = (typeof data.FeatureCollection.featureMember == 'undefined') ? false : true;
					if (dataAvailable) {
								this.senddataasperlayer(data,layer);
					}else {
						GBIF.GeoSpatial.Notice.msg("Exception", "Data not Available");
					}
				}else{
						var dataAvailable = (typeof data.FeatureInfoResponse == 'undefined') ? false : true;
						if (dataAvailable) {
							this.senddataasperlayer(data, layer);
						}else {
							var dataAvailable = (typeof data.ServiceException == 'undefined') ? false : true;
							if (dataAvailable) {
								GBIF.GeoSpatial.Notice.msg("Exception", data.ServiceException);
							}else {
								GBIF.GeoSpatial.Notice.msg("Exception", "Data not Available");
							}
						}	
				}	
			}
	
	,	senddataasperlayer:function(data,layer){
				switch(layer.name) {
					case 'Africa Colonial History':
							var data = data.FeatureInfoResponse.FIELDS;
							break;
					case 'gbif:named_areas':
							var data = data.FeatureCollection.featureMember.named_areas;
							break;
					case 'GBIF: Occurences':
							var data = [data.FeatureCollection.featureMember.cluster10];
							break;	
					case 'GBIF: Cluster10':
							var data = [data.FeatureCollection.featureMember.cluster10];
							break;
					case 'GBIF: Cluster1':
							var data = [data.FeatureCollection.featureMember.cluster1];
							break;				
					case 'GBIF: Cluster100':
							var data = [data.FeatureCollection.featureMember.named_areas];
							break;						
				}
				this.loadinGrid(data, layer.name);
			
			}

	,	loadinGrid:function(data,title){
				Ext.each(this.tabmanager.items.items,function(item){
							if(item.title==title){
									item.store.loadData(data);
									this.tabmanager.setActiveTab(item);		
							}
				},this);
		}

	,	commitdataEditChanges:function(grid){
				var params=[{
							fid:grid.record.data.fid
						,	count:grid.record.data.count	
				}];//Ext.encode(grid.store.data.items);
					
				Ext.Ajax.request({
					url: "../../resources/api/proxy.php"
				,	method: 'POST'
				,	scope:this
				,	params:Ext.encode(params)
				,	success: function(responseObject){
							console.log('save',responseObject);	
	 				}
				}, this);
					//grid.grid.store.save();
			}
	
	,	commitEditChanges:function(grid){
		var vectors=false;
		Ext.each(this.mapComponent.map.layers, function(maplayer){
					if( maplayer.name == "Feature Layer")
							vectors = maplayer;		
		},this);
		var feature = vectors.getFeatureById(grid.record.data.id);
		feature.properties = {
						name: grid.record.data.name
					,	attribute: grid.record.data.attribute
			}
	}

,	controlPanel:function(){
		    			
		/*
		 *	All function is depends on this grid 
		 */
		
		var vectors=false;
		Ext.each(this.mapComponent.map.layers, function(maplayer){
					if( maplayer.name == "Feature Layer")
							vectors = maplayer;		
		},this);
				
		if(!vectors){
			/*vectors = new OpenLayers.Layer.Vector(
					"Feature Layer"
				,	{
						allowOpacity: false
					,	allowDelete: false
					,	checked:true
					}
				);
	*/			
			
		var saveStrategy = new OpenLayers.Strategy.Save();
	
		var vectors = new OpenLayers.Layer.Vector(
				'Feature Layer',
				{protocol: new OpenLayers.Protocol.WFS({
						url: "http://demo.mapfish.org/mapfishsample/1.2/polygons"
				}),
				featuretypes: {
						geometry: {
								type: OpenLayers.Geometry.Polygon
						}
				}
		});
		
		this.mapComponent.map.addLayer(vectors);
	}
		
	var panel = new OpenLayers.Control.Panel();
	var drawpoint= new OpenLayers.Control.DrawFeature(
				vectors
		, 	OpenLayers.Handler.Point
		,	{
				title: "Point Feature"
			,	clickout:true	
			,	displayClass:'olControldrawpoint'
			,	featureAdded:this.callSaveFun
			,	scope:this
			}
	 )
            
	var drawline = new OpenLayers.Control.DrawFeature(
				vectors
		, 	OpenLayers.Handler.Path
		,	{
					title: "Line Feature"
				,	clickout:true
				,	displayClass:'olControldrawline'
				,	featureAdded:this.callSaveFun
				,	scope:this
			}
	)
            
		var drawpolygon = new OpenLayers.Control.DrawFeature(
								vectors
						, 	OpenLayers.Handler.Polygon
						,	{
								title: "Polygon Feature"
							,	clickout:true
							,	displayClass:'olControldrawpolygon'
							,	scope:this
							,	featureAdded:this.callSaveFun
							}
				)

		var remove = new GBIF.GeoSpatial.RemoveFeature(
							vectors
 	                    ,	{	
								title: "Delete Feature"	
							,	onSelect: this.deleteFeature
							,	scope:this
							,	displayClass:'olControlRemoveFeature'
							}
					)
		
		var modify = new OpenLayers.Control.ModifyFeature(
							vectors
						,	{
								title: "Modify Feature"
							,	onModificationEnd:this.callSaveFun
							,	scope:this
							}
						)
		
		var save = new OpenLayers.Control.Button({
		        title: "Save Changes",
		        trigger: function(edit) {
					//console.log("edit",edit);
		            /*if(modify.feature) {
		                modify.selectControl.unselectAll();
		            }*/
				//	console.log("saveStaratery",saveStrategy);
		            saveStrategy.save();
		        },
		        displayClass: "olControlSaveFeatures"
	    });
		
		var SelectFeature= new OpenLayers.Control.SelectFeature(
							vectors
	                    ,	{	title: "Select Feature"	
							,	onSelect:this.onselectfeature	
							,	deactivate:this.unselectFeature 
							,	scope:this
							,	displayClass:"olControlSelectFeature"
							}
						)			
			
		
		
			OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {                
                defaultHandlerOptions: {
                    'single': true,
                },
                initialize: function(options) {
                    this.handlerOptions = OpenLayers.Util.extend(
                        {}, this.defaultHandlerOptions
                    );
                    OpenLayers.Control.prototype.initialize.apply(
                        this, arguments
                    ); 
                    this.handler = new OpenLayers.Handler.Click(
                        this, {
                            'click': this.onClick
                        }, this.handlerOptions
                    );
                }, 

                onClick: function(evt) {
					var xy = evt.xy;
                	Ext.each(this.map.layers,function(maplayer){
							if((typeof maplayer.params == 'undefined')? false : true)
								if (maplayer.params.QUERABLE) {
										GBIF.GeoSpatial.BUS.fireEvent('sendRequest', maplayer,xy, this);
								}
					},this)
				}
		 	});
			
			var activeclick = new OpenLayers.Control.Click({
			    	    title: "Inspect Layers"
					,	allowSelection:true
					,	displayClass: "olControlClickFeature"
        			,	handlerOptions: {
                            "single": true
                        }
					,	trigger: function() {
							Ext.each(panel.controls,function(control){
									if(control.title != 'Single Click'|| control.title != 'Inspect Layers' )
											control.deactivate();
							});
							if(singleclick.active){
								activeclick.deactivate();
							}else{
								activeclick.activate();
							}
						}
    			});
			
			var mouseControl = new OpenLayers.Control.MouseDefaults(
                    {title:'You can use the default mouse configuration'});
					
			
    		panel.addControls(
				[
						mouseControl
					,	remove
					,	modify
					,	SelectFeature
					,	drawpolygon
					,	drawline
					,	drawpoint
					,	activeclick
					,	save
				]
			);
			panel.defaultControl=mouseControl;
			this.mapComponent.map.addControl(panel);		
			panel.activate();
		}
		
	,	moveMapToCenter:function(lon,lat){
				this.mapComponent.map.setCenter(new OpenLayers.LonLat(lon || 0 , lat || 0));
			}
	
	,	unselectFeature: function(){
				this.unselectAll();
				if (this.active) {
			            this.handlers.feature.deactivate();
			            if(this.handlers.box) {
			                this.handlers.box.deactivate();
			            }
			            if(this.layers) {
			                this.map.removeLayer(this.layer);
			            }
			        }
				return OpenLayers.Control.prototype.deactivate.apply(
            			this, arguments
        		)
		//		console.log(this.featuredatagrid );
			}	
	
	,	selectfeaturemap:function(grid,index){
			var rec = grid.store.getAt(index);
			var veclayer;
				Ext.each(this.mapComponent.map.layers, function(maplayer){
						if( maplayer.name == "Feature Layer")
							veclayer = maplayer;		
				},this);
			var feature = veclayer.getFeatureById(rec.data.id);
			var selfeature = this.mapComponent.map.getControlsByClass('OpenLayers.Control.SelectFeature');
			selfeature[0].unselectAll();
			selfeature[0].select(feature);
		}
	
	,	onselectfeature:function(layer){
			this.tabmanager.setActiveTab(this.featuredatagrid);
			var index = this.featuredatagrid.store.findExact("id",layer.fid);
			this.featuredatagrid.getSelectionModel().selectRow(index);
		}
		
	,	savetogrid: function(){
			this.tabmanager.setActiveTab(this.featuredatagrid);
			var point=[];
			Ext.each(this.mapComponent.map.layers, function(maplayer){
				if( maplayer.name == "Feature Layer"){
					maplayer.setZIndex(10000);
					Ext.each(maplayer.features,function(feature){
							feature.fid = feature.id;	
							switch(feature.geometry.CLASS_NAME) {
								case "OpenLayers.Geometry.Point":
									var type = "Point"
									break;
								case "OpenLayers.Geometry.LineString":
									var type = "Line"
									break;
								case "OpenLayers.Geometry.Polygon":
									var type = "Polygon"
									break;
								}
								var data = {
											"geometry": {
													"type": type
												, 	"coordinates": [feature.geometry.bounds.getCenterLonLat()]
												}
										,	state:feature.state
										, 	"type": "Feature"
										, 	"properties": {
														"name": (typeof feature.properties == 'undefined')? "" : feature.properties.name
													,	"attribute": (typeof feature.properties == 'undefined')? "" : feature.properties.attribute                   
												} 
										, "id": feature.id
										}
								point.push(data);
						},this);
					}
				},this);
			this.featuredatagrid.store.loadData(point);	
		}	
	
	,	senddata: function(){
			//var grid = this.featuredatagrid ;
			var params=[];//Ext.encode(grid.store.data.items);
			Ext.each(this.featuredatagrid.store.data.items,function(items){
						params.push(items.json);
				},this);
			Ext.Ajax.request({
				url: "../../resources/api/proxy.php"
			,	method: 'POST'
			,	scope:this
			,	params:Ext.encode(params)
			,	success: function(responseObject){
						console.log('save',responseObject);	
 				}
			}, this);
		}
	
	,	deletefeaturemap:function(){
				Ext.each(this.mapComponent.map.layers, function(maplayer){
						if( maplayer.name == "Feature Layer")
								veclayer = maplayer;		
					},this);
				this.deleteFeature(veclayer.selectedFeatures);	
		}	
	
	,	deleteFeature:function(geometry){
				var veclayer;
				Ext.each(this.mapComponent.map.layers, function(maplayer){
						if( maplayer.name == "Feature Layer")
							veclayer = maplayer;		
				},this);
				veclayer.removeFeatures(geometry);
				this.savetogrid(veclayer);
		}	
});